/**
 * Be warned! Some super complicated math below to get spacing just right.
 */
$form-common-spacing = ($line-height-computed / 2)
// This is a computed value of the amount of spacing that is between the top of the text
// and the top of the line. Basically the amount of spacing around the font in the line.
$line-spacing-above-text = (($line-height-computed - $font-size-base) / 2)

// Form control sizing
//
// Relative text size, padding, and border-radii changes for form controls. For
// horizontal sizing, wrap controls in the predefined grid classes. `<select>`
// element gets special love because it's special, and that's a fact!
input-size(input-height, padding-vertical, padding-horizontal, font-size, line-height, border-radius)
	height: input-height
	padding: padding-vertical padding-horizontal
	font-size: font-size
	line-height: line-height
	border-radius: border-radius

	select&
		height: input-height
		line-height: input-height

	textarea&, select[multiple]&
		height: auto

// Normalize non-controls
//
// Restyle and baseline non-control form elements.
fieldset
	padding: 0
	margin: 0
	border: 0
	// Chrome and Firefox set a `min-width: -webkit-min-content;` on fieldsets,
	// so we reset that to ensure it behaves more like a standard block element.
	// See https://github.com/twbs/bootstrap/issues/12359.
	min-width: 0

legend
	border: 0
	theme-prop('border-bottom-color', 'bg-subtle')
	display: block
	width: 100%
	padding: 0
	margin-bottom: $line-height-computed
	font-size: ($font-size-base * 1.5)
	font-family: $font-family-heading
	font-weight: bold
	line-height: inherit
	border-bottom-width: 1px
	border-bottom-style: solid

label
	display: inline-block
	margin-bottom: 5px
	font-weight: bold

// Normalize form controls
//
// While most of our form styles require extra classes, some basic normalization
// is required to ensure optimum display with or without those classes to better
// address browser inconsistencies.

// Override content-box in Normalize (* isn't specific enough)
input[type='search']
	box-sizing: border-box

// Position radios and checkboxes better
input[type='radio'], input[type='checkbox']
	margin: 4px 0 0
	margin-top: s('1px \9') /* IE8-9 */
	line-height: normal

// Set the height of file controls to match text inputs
input[type='file']
	display: block

// Make range inputs behave like textual form controls
input[type='range']
	display: block
	width: 100%

// Make multiple select elements height not fixed
select[multiple], select[size]
	height: auto

// Focus for file, radio, and checkbox
input[type='file']:focus, input[type='radio']:focus, input[type='checkbox']:focus
	tab-focus()

// Adjust output element
output
	theme-prop('color', 'fg')
	display: block
	padding-top: ($padding-base-vertical + 1)
	font-size: $font-size-base
	line-height: $line-height-base

// Common form controls
//
// Shared size and type resets for form controls. Apply `.form-control` to any
// of the following form controls:
//
// select
// textarea
// input[type="text"]
// input[type="password"]
// input[type="datetime"]
// input[type="datetime-local"]
// input[type="date"]
// input[type="month"]
// input[type="time"]
// input[type="week"]
// input[type="number"]
// input[type="email"]
// input[type="url"]
// input[type="search"]
// input[type="tel"]
// input[type="color"]
.form-control
	theme-prop('color', 'fg')
	change-bg('bg')
	theme-prop('border-color', 'bg-subtle')
	display: block
	width: 100%
	height: $input-height-base // Make inputs at least the height of their button counterpart (base line-height + padding + border)
	padding: $padding-base-vertical $padding-base-horizontal
	font-size: $font-size-base
	line-height: $line-height-base
	background-image: none
	border-width: $border-width-base
	border-style: solid
	border-radius: $input-border-radius
	box-shadow: none
	transition: border-color ease-in-out 0.15s

	&:focus
		theme-prop('border-color', 'fg-muted')
		box-shadow: none
		outline: 0

	// Firefox
	&::-moz-placeholder
		theme-prop('color', 'fg-muted')
		opacity: 1
		font-style: italic

	// Internet Explorer 10+
	&:-ms-input-placeholder
		theme-prop('color', 'fg-muted')
		font-style: italic

	// Safari and Chrome
	&::-webkit-input-placeholder
		theme-prop('color', 'fg-muted')
		font-style: italic

	// Disabled and read-only inputs
	//
	// HTML5 says that controls under a fieldset > legend:first-child won't be
	// disabled if the fieldset is disabled. Due to implementation difficulty, we
	// don't honor that edge case; we style them as disabled anyway.
	&[disabled], &[readonly], fieldset[disabled] &
		change-bg('bg-offset')
		cursor: not-allowed
		opacity: 1 // iOS fix for unreadable disabled content

	// Reset height for `textarea`s
	textarea&
		height: auto
		resize: vertical

// Search inputs in iOS
//
// This overrides the extra rounded corners on search inputs in iOS so that our
// `.form-control` class can properly style them. Note that this cannot simply
// be added to `.form-control` as it's not specific enough. For details, see
// https://github.com/twbs/bootstrap/issues/11586.
input[type='search']
	-webkit-appearance: none

// Special styles for iOS date input
//
// In Mobile Safari, date inputs require a pixel line-height that matches the
// given height of the input.
input[type='date']
	line-height: $input-height-base

// Form groups
//
// Designed to help with the organization and spacing of vertical forms. For
// horizontal forms, use the predefined grid classes.
// Try to match heading style.
.form-group
	margin-bottom: ($line-height-computed * 1.5)

	&.optional .control-label:after
		theme-prop('color', 'fg-muted')
		content: ' (optional)'
		font-size: 85%

// Control labels
//
// Space the bottom of the control label away from its control.
.control-label
	font-family: $font-family-heading
	margin-bottom: $form-common-spacing

// Checkboxes and radios
//
// Indent the labels to position radios/checkboxes as hanging controls.
.radio, .checkbox
	display: block
	min-height: $line-height-computed // clear the floating input if there is no label text
	margin-top: 10px
	margin-bottom: 10px
	padding-left: 20px

	label
		display: inline
		font-weight: normal
		cursor: pointer

.radio input[type='radio'], .radio-inline input[type='radio'], .checkbox input[type='checkbox'], .checkbox-inline input[type='checkbox']
	float: left
	margin-left: -20px
	// Make pointers!
	cursor: pointer

.radio + .radio, .checkbox + .checkbox
	margin-top: -5px // Move up sibling radios or checkboxes for tighter spacing

// Radios and checkboxes on same line
.radio-inline, .checkbox-inline
	display: inline-block
	padding-left: 20px
	margin-bottom: 0
	vertical-align: middle
	font-weight: normal
	cursor: pointer

.radio-inline + .radio-inline, .checkbox-inline + .checkbox-inline
	margin-top: 0
	margin-left: 10px // space out consecutive inline controls

// Apply same disabled cursor tweak as for inputs
//
// Note: Neither radios nor checkboxes can be readonly.
input[type='radio'], input[type='checkbox'], .radio, .radio-inline, .checkbox, .checkbox-inline
	&[disabled], fieldset[disabled] &
		cursor: not-allowed

.checkbox, .checkbox-inline, .radio, .radio-inline
	// Want any jolticons to be a pointer as well.
	label > .jolticon
		cursor: pointer

	// Disabled styling for checkboxes and radios.
	&.disabled
		theme-prop('color', 'fg-muted')

		&, & > label, & > label > .jolticon
			cursor: not-allowed

// Form control sizing
//
// Build on `.form-control` with modifier classes to decrease or increase the
// height and font-size of form controls.
input-sm()
	input-size($input-height-small, $padding-small-vertical, $padding-small-horizontal, $font-size-small, $line-height-small, $border-radius-small)

.input-sm
	input-sm()

// Static form control text
//
// Apply class to a `p` element to make any string of text align with labels in
// a horizontal form layout.
.form-control-static
	margin-bottom: 0 // Remove default margin from `p`

// Help text
//
// Apply to any element you wish to create light text for placement immediately
// below a form control. Use for general help, formatting, or instructional text.
// Space the top of the help block away from its control.
// We assume that a form control/error message will usually follow the help block.
// So we put our common spacing below, plus the extra spacing since there won't be any normal text line following.
.help-block
	theme-prop('color', 'fg-muted')
	display: block // account for any element using help-block
	margin-top: $form-common-spacing
	margin-bottom: $form-common-spacing + $line-spacing-above-text
	font-size: 14px

	&.strong
		font-weight: bold

legend + .help-block
	margin-top: 0

.help-inline
	theme-prop('color', 'fg-muted')
	font-size: 14px

// If a help block immediately follows a control label, then the control label
// has the spacing and we don't need to space.
.control-label + .help-block
	margin-top: 0

// Notice that our errors have the normal margin bottom spacing.
.help-block.error
	rounded-corners-lg()
	change-bg('notice')
	theme-prop('color', 'notice-fg', true)
	position: relative
	padding: 10px
	margin-top: 7px
	margin-bottom: $form-common-spacing
	font-size: $font-size-base

	&:before
		caret(color: var(--theme-notice), direction: 'up', size: 5px)
		content: ''
		display: block
		left: 10px

	// For when the help block is above, swap the spacing.
	&.above
		margin-bottom: 7px
		margin-top: $form-common-spacing

		&:before
			display: none

		&:after
			caret(color: var(--theme-notice), direction: 'down', size: 5px)
			content: ''
			display: block
			left: 10px

	&.hide-caret
		&:before, &:after
			display: none

// Inline forms
//
// Make forms appear inline-block by adding the `.form-inline` class. Inline
// forms begin stacked on extra small (mobile) devices and then go inline when
// viewports reach <768px.
//
// Requires wrapping inputs and labels with `.form-group` for proper display of
// default HTML form controls and our custom form controls (e.g., input groups).
//
// Heads up! This is mixin-ed into `.navbar-form` in navbars.less.
.form-inline
	// Kick in the inline
	@media $media-min-tablet
		// Inline-block all the things for "inline"
		.form-group
			display: inline-block
			margin-bottom: 0
			vertical-align: middle

		// In navbar-form, allow folks to *not* use `.form-group`
		.form-control
			display: inline-block
			width: auto // Prevent labels from stacking above inputs in `.form-group`
			vertical-align: middle

		// Input groups need that 100% width though
		.input-group > .form-control
			width: 100%

		.control-label
			margin-bottom: 0
			vertical-align: middle

		// Remove default margin on radios/checkboxes that were used for stacking, and
		// then undo the floating of radios and checkboxes to match (which also avoids
		// a bug in WebKit: https://github.com/twbs/bootstrap/issues/1969).
		.radio, .checkbox
			display: inline-block
			margin-top: 0
			margin-bottom: 0
			padding-left: 0
			vertical-align: middle

		.radio input[type='radio'], .checkbox input[type='checkbox']
			float: none
			margin-left: 0

// Horizontal forms
//
// Horizontal forms are built on grid classes and allow you to create forms with
// labels on the left and inputs on the right.
.form-horizontal
	// Consistent vertical alignment of labels, radios, and checkboxes
	.control-label, .radio, .checkbox, .radio-inline, .checkbox-inline
		margin-top: 0
		margin-bottom: 0
		padding-top: ($padding-base-vertical + 1) // Default padding plus a border

	// Account for padding we're adding to ensure the alignment and of help text
	// and other content below items
	.radio, .checkbox
		min-height: ($line-height-computed + ($padding-base-vertical + 1))

	// Make form groups behave like rows
	.form-group
		make-row()

	.form-control-static
		padding-top: ($padding-base-vertical + 1)

	// Only right align form labels here when the columns stop stacking
	@media $media-min-tablet
		.control-label
			text-align: right
